Spring Cloud Alibaba Nacos


Spring Cloud Alibaba 是一个遵循 Spring Cloud 变成规范的框架,也就是 Alibaba 所推出的微服务解决方案,他主要分为 Sentinel(流量控制)、Nacos(服务发现)、RocketMQ(分布式消息系统)、Dubbo(高性能 Java RPC 框架)、Seata(高性能微服务事务解决方案)、ACM(配置中中心)、OSS(对象存储服务)、SchedulerX(分布式任务调度)、SMS(短信服务)

Alibaba 对为 Spring Cloud 的贡献同样可以与 Netfilx 相同的产品都有类似的解决方案,但在 Spring Cloud 中 Netfilx 的贡献要比 Alibaba 早上许多,因此通常 Alibaba 的解决方案依然可以替换掉 Netfilx 的产品,但 Netfilx 同样也可以替换掉 Alibaba 的解决方案,与其相比之下 Alibaba 的解决方案更加的简洁,通常一个项目可以代替很多个 Netfilx 的子项目。

Nacos 是 Alibaba Spring Cloud 中用于构建微服务应用与服务治理的配置管理组建,与 Eureka、Conusl 同样分为服务中心、服务提供者、服务消费者等三个角色,除此之外还可以直接实现配置中心的服务。

在实现服务提供者和消费者之前,我们首先需要通过 Nacos 仓库来下载其发行版本的服务中心,需要注意的是环境环境依赖是:

  1. 64bit 支持 Linux\Unix\Mac\Windows(官方推荐 Linux\Mac\Unix)
  2. JDK 1.8+
  3. Maven 3.2.+

满足依赖环境后可以通过 https://github.com/alibaba/nacos/releases/tag/2.0.3 来获取你想要的版本进行下载。

之后解压进入 bin 目录,并运行 ./startup.sh -m standalone 命令以启动 Nacos,并访问 http://localhost:8848/nacos 即可登入 nacos 的控制台,帐号密码均为 nacos,因此服务中心的地址为 localhost:8848

服务治理

服务提供者


我们首先创建两个服务提供者,并连接服务中心,之后进行配置,在默认情况下我们需要引入 spring-boot-starter-web、spring-cloud-starter-alibaba-nacos-discovery 依赖以作为必要的服务支撑:

1
2
3
4
5
6
7
8
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

同样的我们需要进行配置连接服务中心以及名称等,以便在微服务系统中发现该功能是那个服务所提供的,因此好进行改进和调整,配置后我们还需要在启动类中添加 @EnableDiscoveryClient 依赖

1
2
3
4
5
6
7
8
9
10
spring:
application:
name: localhost-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848

server:
port: 8210

heyController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* 提供者控制器
*
* @author kunlun
* @date 2021/8/1
*/
@RestController
public class heyController {

@Value("${spring.application.name}")
private String appName;

@GetMapping("/hey")
public String hey() {
String sty = "This is Provider: " + appName + "-1";
return sty;
}

}

从上所述我们的服务提供者所提供的基础服务已经构建完成,在演示中我们构建的是两个服务提供者,都提供同样的功能,端口为 8210~8211 ,为两个服务提供者,之后我们可以编写服务消费者。

服务消费者

至于服务消费者,我们同样的需要引入 spring-cloud-starter-alibaba-nacos-discovery 依赖以及负载均衡 feign 依赖,和一些基础服务提供依赖,来完成服务消费者的构建,在此之前我们需要在启动类中添加 @EnableDiscoveryClient 注解并完善配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

配置文件的主要作用同样是配置服务名称以及连接服务中心等:

1
2
3
4
5
6
7
8
9
spring:
application:
name: localhost-consumer
cloud:
nacos:
server-addr: 127.0.0.1:8848

server:
port: 8310

heyController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.example.demo.controller;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;

/**
* @author kunlun
* @date 2021/7/31
*/
@RestController
@EnableDiscoveryClient
public class heyController {

@Autowired
private LoadBalancerClient loadBalancerClient;

@Autowired
private RestTemplate restTemplate;

@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}

@Value("${spring.application.name}")
private String appName;

@GetMapping("/hey")
public String echoApplication() {
ServiceInstance serviceInstance = loadBalancerClient.choose("localhost-provider");
URI uri = serviceInstance.getUri();
String callService = new RestTemplate().getForObject(uri + "/hey", String.class);
return callService;
}

}

配置中心

相对与之前的 Spring Cloud Config ,Alibaba 所提供的 Spring Cloud Aliababa Config 主要依赖于服务中心的分发与配置,同时还支持配置动态刷新,以及达到和 Spring Cloud Config 相同效果的配置文件应用,只需要依赖 spring-cloud-starter-alibaba-nacos-config 即可,在此之前我们还需要在启动类中加入 @EnableDiscoveryClient 依赖:

1
2
3
4
5
6
7
8
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

在此之前,我们需要在服务中心中新建一个 .properties 类型的文件,当然他默认支持了 TEXT、JSON、XML、YAML、HTML、Properties 等配置格式,我们只需要填写配置信息和 Data ID 即可:

1
2
3
app.version=rsa
message=Spring Cloud Alibaba Config Server
server.port=9510

bootstrap.yml & application.yml

bootstrap.yml

1
2
3
4
5
spring:
cloud:
nacos:
config:
refreshable-dataids: server-config-example.properties

我们通过 refreshable-dataids 来绑定配置文件的名称,之后通过服务中心进行获取,因为是从服务中心直接获取,从而省去了很多配置。

application.yml

1
2
3
4
5
6
7
8
9
spring:
application:
name: localhost-consumer
cloud:
nacos:
server-addr: 127.0.0.1:8848

server:
port: 8410

Controller


控制器主要作用就是通过服务中心以及配置所绑定的文件,来获取到服务中心的配置文件信息,并通过指定接口来进行输出,当一切开始运行后访问 http://localhost:9510/hey 即可看到从服务中心和控制器所输出的信息。

ServerConfigController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* 获取服务中心配置文件信息
*
* @author kunlun
* @date 2021/8/1
*/
@RestController
@RefreshScope
public class ServerConfigConortller {

@Value("${app.version}")
private String appVersion;

@Value("${message}")
private String message;

@RequestMapping("/hey")
public String hey() {
return "application: " + appVersion + " message: " + message;
}
}

本文使用《江雪分析公开知识存储库知识共享许可证》进行发布